home *** CD-ROM | disk | FTP | other *** search
- (herald mipsco_link (env t (link defs)))
-
- ;;; Look at a Unix a.out description and template.doc
-
- (define (link modules out-spec)
- (really-link modules 'mbo out-spec 'o))
-
- (define-constant RELOC-SIZE 8)
- (define-constant MAGIC #x160)
- (define-constant TEXT-SYM 1)
- (define-constant DATA-SYM 3)
-
- (lset reloc-length 0)
- (lset pure-size 0)
-
- (define-constant %%d-ieee-size 53)
- (define-constant %%d-ieee-excess 1023)
-
- (define (write-double-float stream float)
- (receive (sign mantissa exponent)
- (normalized-float-parts float
- %%d-ieee-size
- %%d-ieee-excess
- t)
- (write-int stream header/double-float)
- (write-half stream (fx+ (fixnum-ashl sign 15)
- (fx+ (fixnum-ashl exponent 4)
- (bignum-bit-field mantissa 48 4))))
- (write-half stream (bignum-bit-field mantissa 32 16))
- (write-half stream (bignum-bit-field mantissa 16 16))
- (write-half stream (bignum-bit-field mantissa 0 16))))
-
- (define (write-vcell-header var stream)
- (write-half stream 0)
- (write-byte stream (if (fx= (vector-length (var-node-refs var))
- 0)
- 0
- -1))
- (write-byte stream (if (eq? (var-node-defined var) 'define)
- (fx+ header/vcell 128)
- header/vcell)))
-
-
-
- (define (vgc-copy-foreign foreign)
- (let* ((heap (lstate-impure *lstate*))
- (addr (area-frontier heap))
- (name (foreign-object-name foreign))
- (desc (object nil
- ((heap-stored self) (lstate-impure *lstate*))
- ((heap-offset self) addr)
- ((write-descriptor self stream)
- (write-data stream (fx+ addr tag/extend)))
- ((write-store self stream)
- (write-int stream header/foreign)
- (write-slot name stream)
- (write-int stream 0)))))
- (set (area-frontier heap) (fx+ addr 12))
- (set-table-entry *reloc-table* foreign desc)
- (generate-slot-relocation name (fx+ addr 4))
- (push (area-objects heap) desc)
- (cymbal-thunk (symbol->string name) 0)
- (reloc-thunk (fx+ addr 8) (lstate-symbol-count *lstate*) 5)
- (modify (lstate-symbol-count *lstate*) (lambda (x) (fx+ x 1)))
- desc))
-
- (define (relocate-unit-variable var addr external?)
- (let ((area (lstate-impure *lstate*))
- (type (var-value-type var)))
- (cond (type
- (cond ((and external? (neq? (var-node-value var) NONVALUE))
- (cymbal-thunk (string-downcase! (symbol->string (var-node-name var)))
- (unit-var-value (var-node-value var)))
- (modify (lstate-symbol-count *lstate*) (lambda (x) (fx+ x 1)))))
- (if (fx= type DATA-SYM)
- (reloc-thunk addr DATA-SYM 4)
- (reloc-thunk addr TEXT-SYM 4))))))
-
-
- (define (var-value-type var)
- (let ((value (var-node-value var)))
- (cond ((eq? value NONVALUE)
- (vgc (var-node-name var))
- nil)
- ((unit-loc? value) DATA-SYM)
- (else
- (let ((desc (vgc value)))
- (if (eq? (heap-stored desc) (lstate-impure *lstate*))
- DATA-SYM
- TEXT-SYM))))))
-
- (define (generate-slot-relocation obj slot-address)
- (cond ((or (fixnum? obj) (char? obj) (eq? obj '#t)))
- ((eq? (heap-stored (vgc obj)) (lstate-impure *lstate*))
- (reloc-thunk slot-address DATA-SYM 4))
- (else
- (reloc-thunk slot-address TEXT-SYM 4))))
-
- (define (text-relocation addr)
- (reloc-thunk addr TEXT-SYM 4))
-
- (define (data-relocation addr)
- (reloc-thunk addr DATA-SYM 4))
-
- (define (reloc-thunk address lw hb)
- (push (lstate-data-reloc *lstate*)
- (cons address (cons lw hb))))
-
- (lset the-string-table nil)
-
- (define (cymbal-thunk stryng value)
- (push (lstate-symbols *lstate*)
- (object (lambda (stream)
- (write-int stream 0)
- (write-int stream (table-entry the-string-table stryng))
- (cond ((fx= value 0) ; undefined external (foreign)
- (write-int stream 0)
- (write-half stream #x4cf))
- (else
- (write-data stream value)
- (write-half stream #x44f)))
- (write-half stream #xffff))
- ((cymbal-thunk.stryng self) stryng))))
-
- (define-operation (cymbal-thunk.stryng thunk))
-
-
- (define (write-slot obj stream)
- (cond ((table-entry *reloc-table* obj)
- => (lambda (desc) (write-descriptor desc stream)))
- ((fixnum? obj)
- (write-fixnum stream obj))
- ((char? obj)
- (write-int stream (fx+ (fixnum-ashl (char->ascii obj) 8)
- header/char)))
- ((eq? obj '#t)
- (write-int stream header/true))
- (else
- (error "bad immediate type ~s" obj))))
-
- (define-integrable (write-data stream int)
- (write-int stream (fx+ pure-size int)))
-
- (define-integrable (write-int stream int)
- (write-half stream (fixnum-ashr int 16))
- (write-half stream int))
-
- (define (write-half stream int)
- (write-byte stream (fixnum-ashr int 8))
- (write-byte stream int))
-
- (define-integrable (write-byte stream n)
- (writec stream (ascii->char (fixnum-logand n 255))))
-
- (define-integrable (write-fixnum stream fixnum)
- (write-half stream (fixnum-ashr fixnum 14))
- (write-half stream (fixnum-ashl fixnum 2)))
-
-
- (define (write-link-file stream)
- (set reloc-length (enforce (lambda (x) (<= x #xffff))
- (length (lstate-data-reloc *lstate*))))
- (modify (lstate-symbols *lstate*) reverse!)
- (pad-area (lstate-pure *lstate*))
- (pad-area (lstate-impure *lstate*))
- (set pure-size (area-frontier (lstate-pure *lstate*)))
- (write-header stream)
- (write-aouthdr stream)
- (write-text-section-header stream)
- (write-data-section-header stream)
- (write-area stream (lstate-pure *lstate*))
- (write-area stream (lstate-impure *lstate*))
- (write-relocation stream)
- (receive (i aligned-i) (make-stryng-table)
- (write-cymbal-table-header stream aligned-i)
- (write-hack-local-symbol stream)
- (write-hack-local-string stream)
- (write-stryng-table stream (fx- aligned-i i)))
- (write-hack-file-descriptor stream)
- (write-cymbal-table stream))
-
- (define (write-header stream)
- (write-half stream MAGIC) ;magic number
- (write-half stream 2) ; # of sections
- (write-int stream 0) ; time and date
- (write-int stream (cymbal-table-offset))
- (write-int stream #x60) ;size of symbol header
- (write-half stream #x38) ; size of a.out header
- (write-half stream 0)) ;flags
-
- (define (write-aouthdr stream)
- (write-half stream #x107) ;magic
- (write-half stream #x11f) ;version stamp
- (write-int stream (text-size)) ;text size
- (write-int stream (data-size)) ;data size
- (write-int stream 0) ;bss size
- (write-int stream 0) ;entry
- (write-int stream 0) ;text base
- (write-int stream (text-size)) ;data base
- (write-int stream (+ (text-size) (data-size))) ;bss base
- (write-int stream 0) ;register mask
- (write-int stream 0) ;cp mask [4]
- (write-int stream 0)
- (write-int stream 0)
- (write-int stream 0)
- (write-int stream #x8010)) ;gp value ???
-
-
- (define (write-text-section-header stream)
- (write-string stream ".text")
- (write-byte stream 0)
- (write-byte stream #x20)
- (write-byte stream #x20)
- (write-int stream 0) ; phys addr
- (write-int stream 0) ; virtual addr
- (write-int stream (text-size))
- (write-int stream (headers-size)) ;offset in file
- (write-int stream 0) ; no reloc
- (write-int stream 0) ; no gp table
- (write-int stream 0)
- (write-int stream #x20))
-
- (define (write-data-section-header stream)
- (write-string stream ".data")
- (write-byte stream 0)
- (write-byte stream #x20)
- (write-byte stream #x20)
- (write-int stream (text-size)) ; phys addr
- (write-int stream (text-size)) ; virtual addr
- (write-int stream (data-size))
- (write-int stream (+ (text-size) (headers-size))) ;offset in file
- (write-int stream (+ (headers-size) (text-size) (data-size))) ; reloc
- (write-int stream 0) ; no gp table
-
- (write-half stream reloc-length)
- (write-half stream 0) ;no gp tables
- (write-int stream #x40))
-
- (define (headers-size) (fx* 39 4))
- (define (text-size) (area-frontier (lstate-pure *lstate*)))
- (define (data-size) (area-frontier (lstate-impure *lstate*)))
-
- (define (cymbal-table-offset)
- (+ (headers-size) (text-size) (data-size)
- (* RELOC-SIZE reloc-length)))
-
- (define (write-area stream area)
- (walk (lambda (x) (write-store x stream))
- (reverse! (area-objects area))))
-
-
- (define (write-relocation stream)
- (walk (lambda (item)
- (destructure (((addr . (lw . hb)) item))
- (write-data stream (car item))
- (write-byte stream 0)
- (write-half stream lw)
- (write-byte stream hb)))
- (sort-list! (lstate-data-reloc *lstate*)
- (lambda (x y)
- (fx< (car x) (car y))))))
-
-
- (define (write-map-entry stream name value) nil)
-
- (define (write-cymbal-table-header stream string-table-size)
- (write-half stream #x7009) ;magic
- (write-half stream #x11f) ;vstamp
- (write-long-zeros stream 7)
- (write-int stream 2) ;number of local symbols
- (write-int stream (+ (cymbal-table-offset) #x60))
- (write-long-zeros stream 4)
- (write-int stream 8) ;max index in local strings
- (write-int stream (+ (cymbal-table-offset) #x60 24))
- (write-int stream string-table-size) ;max string-index
- (write-int stream (+ (cymbal-table-offset) #x60 8 24)) ;string table begin
- (write-int stream 1) ;fd entries
- (write-int stream (+ (cymbal-table-offset) #x60 8 24 string-table-size))
- (write-long-zeros stream 2)
- (write-int stream (lstate-symbol-count *lstate*)) ;max symbol index
- (write-int stream (+ (cymbal-table-offset) #x60 8 24 string-table-size 72)))
-
- (define (write-hack-local-symbol stream)
- (write-int stream 1)
- (write-int stream 0)
- (write-half stream #x2c20)
- (write-half stream 2)
- (write-int stream 1)
- (write-int stream 0)
- (write-half stream #x2020)
- (write-half stream 0))
-
- (define (write-hack-local-string stream)
- (write-byte stream 0)
- (write-string stream "foo.s")
- (write-byte stream 0)
- (write-byte stream 0))
-
- (define (write-hack-file-descriptor stream)
- (walk (lambda (x) (write-int stream x))
- '(0 1 0 7 0 2 0 0 0 0 0 0 0 0 0))
- (write-half stream #x1d80)
- (write-half stream 0)
- (write-int stream 0)
- (write-int stream 0))
-
- (define (write-long-zeros stream n)
- (do ((i n (fx- i 1)))
- ((fx= i 0))
- (write-int stream 0)))
-
- (define (write-cymbal-table stream)
- (walk (lambda (cym) (cym stream)) (lstate-symbols *lstate*)))
-
- (define (make-stryng-table)
- (set the-string-table (make-string-table 'stryngs))
- (iterate loop ((i 0) (cyms (lstate-symbols *lstate*)))
- (cond ((null? cyms) (return i (align i 2)))
- (else
- (let* ((string (cymbal-thunk.stryng (car cyms)))
- (len (string-length string)))
- (set (table-entry the-string-table string) i)
- (loop (fx+ i (fx+ len 1)) (cdr cyms)))))))
-
-
- (define (write-stryng-table stream extra)
- (walk (lambda (cym)
- (write-string stream (cymbal-thunk.stryng cym))
- (write-byte stream 0))
- (lstate-symbols *lstate*))
- (do ((extra extra (fx- extra 1)))
- ((fx= extra 0))
- (write-byte stream 0)))
-
-
- (define (pad-area area)
- (let ((rem (fixnum-remainder (area-frontier area) 16)))
- (cond ((fxn= rem 0)
- (modify (area-frontier area)
- (lambda (x) (fx+ x (fx- 16 rem))))
- (do ((i (fx- 16 rem) (fx- i 4)))
- ((fx= i 0))
- (push (area-objects area)
- (object nil
- ((write-store self stream)
- (write-int stream 0)))))))))